// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "SurveillanceCameraManager.generated.h"


class USurveillanceSubWindow;
class USceneCaptureComponent2D;
class USurveillanceControlWidget;


struct FCreatedWindowInfo
{
	int32 Row;
	int32 Column;
	TSubclassOf<USurveillanceSubWindow> SubWindowType;
	float Padding;
};

USTRUCT()
struct FSurveillanceCamera
{
	GENERATED_BODY()

	UPROPERTY(EditDefaultsOnly)
	FName Name;
	
	// 附加的组件名称
	UPROPERTY(EditDefaultsOnly, Category="Surveillance|ParentComponent")
	FName Parent;

	UPROPERTY(EditDefaultsOnly, Category="Surveillance|Transform")
	FTransform RelativeTransform;

	UPROPERTY(EditDefaultsOnly, Category="Surveillance|Transform")
	bool bGlobal = false;

	UPROPERTY(EditDefaultsOnly, Category="Surveillance|Debug")
	bool bDebug = false;
	
	UPROPERTY(EditDefaultsOnly, Category="Surveillance|Debug")
	float DebugScale = 5.f;

	UPROPERTY(EditDefaultsOnly, Category="Surveillance|Debug")
	FColor DebugColor = FColor::Blue;

	TObjectPtr<USceneComponent> ParentCmp;
	TWeakObjectPtr<USceneCaptureComponent2D> SceneCaptureComponent2D;
	TWeakObjectPtr<UMaterialInstanceDynamic> ViewMaterial;
	FTransform ActualTransform;
	FQuat GlobalQuat;
};


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class SURVEILLANCECAMERA_API USurveillanceCameraManager : public UActorComponent
{
	GENERATED_BODY()

public:	
	USurveillanceCameraManager();

	/**
	 * 监控相机个数
	 */
	UFUNCTION(BlueprintPure, Category="SurveillanceCamera")
	FORCEINLINE int32 GetSurveillanceCameraNumber() const {return SurveillanceCameras.Num();};

	/**
	 * 是否开启相机 Debug
	 * @param Debug 
	 * @param Index 相机序号
	 */
	void DebugCamera(bool Debug, int32 Index);
	/**
	 * 获取对应序号的相机名称
	 */
	UFUNCTION(BlueprintPure, Category="SurveillanceCamera")
	FORCEINLINE FName GetCameraNameAtIndex(int32 Index) const
	{
		if (Index >= SurveillanceCameras.Num())
			return FName{};

		return SurveillanceCameras[Index].Name;
	};

	/**
	 * 设置相机偏移
	 * @param Offset 
	 * @param CameraIndex 相机索引
	 */
	void SetCameraOffset(FVector Offset, int32 CameraIndex);

	/**
	 * 设置相机旋转
	 * @param Rotator 
	 * @param CameraIndex 
	 */
	void SetCameraRotation(FRotator Rotator, int32 CameraIndex);

	/**
	 * 设置相机保持全局旋转
	 * @param Global 
	 * @param Index 
	 */
	void SetCameraGlobal(bool Global, int32 Index);

	/**
	 * 设置相机激活
	 * @param Active 
	 */
	void SetCameraActive(bool Active, int32 Index);

	/**
	 * 设置相机分辨率
	 * @param val 
	 * @param Index 
	 */
	void SetCameraResolution(int32 Resolution, int32 Index);

	/**
	 * 设置相机 FOV
	 * @param Fov 
	 * @param Index 
	 */
	void SetCameraFocalLength(int32 FocalLength, int32 Index);
	
	/**
	 * 创建监控窗口
	 * @param Row 行数
	 * @param Column 列数
	 */
	UFUNCTION(BlueprintCallable, Category="SurveillanceCamera")
	void CreateSurveillanceWnd(int32 Row, int32 Column, TSubclassOf<USurveillanceSubWindow> SurveillanceSubWindowClass, float Padding=5.f);

	/**
	 * 刷新窗口显示
	 */
	UFUNCTION(BlueprintCallable, Category="SurveillanceCamera")
	void RefreshSurveillanceWnd();


	void CreateSceneCaptureAndRenderTarget();

	/**
	 * 添加额外相机
	 * @param Avatar 
	 */
	UFUNCTION(BlueprintCallable, Category="SurveillanceCamera|Extra")
	void BindExtraCameraWithActor(AActor* Avatar);

	/**
	 * 移除额外相机
	 * @param Avatar
	 */
	UFUNCTION(BlueprintCallable, Category="SurveillanceCamera|Extra")
	void RemoveExtraCameraWithActor(AActor* Avatar);

	/**
	 * 设置额外相机名称
	 * @param Avatar 
	 * @param Name 
	 */
	UFUNCTION(BlueprintCallable, Category="SurveillanceCamera|Extra")
	void SetExtraCameraName(AActor* Avatar, FName Name);

	/**
	 * 设置额外相机分辨率
	 * @param Avatar 
	 * @param Resolution 
	 */
	UFUNCTION(BlueprintCallable, Category="SurveillanceCamera|Extra")
	void SetExtraCameraResolution(AActor* Avatar, int32 Resolution);

	/**
	 * 设置额外相机 FOV
	 */
	UFUNCTION(BlueprintCallable, Category="SurveillanceCamera|Extra")
	void SetExtraCameraFocalLength(AActor* Avatar, float FocalLength);
protected:
	virtual void BeginPlay() override;

public:	
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
private:
	UPROPERTY(EditDefaultsOnly, Category="SurveillanceCamera")
	TObjectPtr<class UMaterial> RenderTargetMaterial;
	
	UPROPERTY(EditDefaultsOnly, Category="SurveillanceCamera")
	TArray<FSurveillanceCamera> SurveillanceCameras;

	// 额外的相机
	TMap<TWeakObjectPtr<AActor>, FSurveillanceCamera> ExtraCameraMap;

	TSharedPtr<SWindow> SurveillanceWindow;

	float SensorAspectRatio = 16.f / 9.f; // 宽高比
	float SensorWidth = 23.76f; // 进光传感器宽


// ----------------------------------------- Refresh Window ---------------------------------------------
	FCreatedWindowInfo CreatedWindowInfo;
	
	FTimerHandle TH_DelayToNextTick;

	/**
	 * 延迟到下一帧 创建窗口
	 */
	UFUNCTION()
	void DelayToCreateWindow();
};

